<!-- TODO objform显示标题可配，错误信息优化
隐藏的组件的值的问题
 -->
<style lang="scss" scoped>
</style>
<template>
  <el-form :label-width="config.labelWidth" :inline="config.inline" class="mlform">

    <formItem
      v-for="item in config.dataList"
      ref="formItem"
      :key="item.key"
      :config="item"
      :value="val[item.key]"
      :base-root-val="baseRootVal"
      :base-parent-val="baseParentVal"
      :base-this-val = "val"
      :config-all="config"
      @input="change(item.key,$event)"
      @hide="hide"
      @show="show(item,$event)"
    />

  </el-form>
</template>
<script>
import formItem from './formItem.vue'
import { copyObj } from '@/utils'
export default {
  components: {
    formItem
  },
  props: {
    value: {
      type: null,
      required: true
    },
    config: {
      type: Object,
      required: true
    },
    rootVal: {
      type: null,
      required: false,
      default: null
    },
    parentVal: {
      type: null,
      required: false,
      default: null
    }
  },
  data() {
    return {
      initValue: this.value || {}
      // init: true
      // val: initVal,
      // {
      //   "value": "address",
      //   "label": "地址选择"
      // },
    }
  },

  computed: {
    val() {
      let obj = {}
      if (typeof this.value === 'object') {
        obj = this.value
      }
      return Object.assign(this.initVal(), obj)
    },
    // 获得form 的值的对象 根和父，objform 父必传
    baseRootVal() {
      if (this.rootVal) {
        return this.rootVal
      } else {
        return this.val
      }
    },
    baseParentVal() {
      if (this.parentVal) {
        return this.parentVal
      } else {
        return this.val
      }
    }
  },

  created() {},

  mounted() {},

  methods: {
    clearValidate() {
      for (var i = 0; i < this.$refs['formItem'].length; i++) {
        this.$refs['formItem'][i].clearValidate()
      }
    },
    // 验证数据
    validate() {
      let validateResult = true
      for (var i = 0; i < this.$refs['formItem'].length; i++) {
        if (!this.$refs['formItem'][i].validate()) {
          validateResult = false
        }
      }
      return validateResult
    },
    validateNoMsg() {
      let validateResult = true
      for (var i = 0; i < this.$refs['formItem'].length; i++) {
        if (!this.$refs['formItem'][i].validateNoMsg()) {
          validateResult = false
        }
      }
      return validateResult
    },
    // 初始化数据
    initVal() {
      const list = this.config.dataList
      const objInit = {}
      list.forEach(data => {
        objInit[data.key] = this.getValByType(data)
      })
      return objInit
    },
    // 重置初始值
    reset() {
      this.clearValidate()
      this.$emit('input', copyObj(Object.assign(this.initVal(), this.initValue)))
    },
    // 为各种类型的设置初始值  arrayObj类型时候，直接调用form组件
    // TODO: 下拉是否多选
    // 地址、时间 初始值
    getValByType(obj) {
      if (obj.value) {
        return obj.value
      } else if (obj.type === 'boolean') {
        return false
      } else if (
        obj.type === 'checkbox' ||
        (obj.type === 'select' && obj.multiple)
      ) {
        return []
      } else if (
        (obj.type === 'select' && obj.must && !obj.multiple) ||
        (obj.type === 'radio' && obj.must)
      ) {
        for (var i = 0; i < obj.options.length; i++) {
          if (!obj.options[i].disabled) {
            return obj.options[i].value
          }
        }
        return null
      } else if (obj.type === 'object') {
        return []
      } else {
        return null
      }
    },
    // 监听值改变
    change(key, val) {
      const obj = copyObj(this.val)
      obj[key] = val
      this.$emit('input', obj)
    },
    hide(key) {
      const obj = copyObj(this.val)
      if (this.config.dataList.filter(obj => obj.key === key).length === 1) {
        delete obj[key]
        this.$emit('input', obj)
      }
    },
    show(item, val) {
      const obj = copyObj(this.val)
      obj[item.key] = val || this.getValByType(item)
      this.$emit('input', obj)
    }
  }
}
</script>
